﻿namespace OverStore.Sql.TableSchema
{
    using System;
    using System.Data;

    /// <summary>
    /// Base class for <see cref="Table"/> column.
    /// </summary>
    public abstract class ColumnBase
    {
        private bool? _AllowNull;
        private string _ResultSetName;

        /// <summary>
        /// Gets or sets the name of column in database table.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the name of the parameter used for provide result for column, or name of column in resultset populated by SELECT statement.
        /// If result of this property is not set or set to null, parameter name will be equal to <see cref="Name"/>.
        /// </summary>
        public string ResultSetName
        {
            get
            {
                return _ResultSetName ?? Name;
            }

            set
            {
                _ResultSetName = value;
            }
        }

        /// <summary>
        /// Gets or sets the string used as message for exception that is thrown if value for the parameter corresponding to the column is invalid.
        /// </summary>
        public string ErrorMessage { get; set; }

        /// <summary>
        /// Gets or sets a result indicating whether colum allows null result.
        /// </summary>
        /// <result><c>true</c> if column allows null values; otherwise, <c>false</c>.</result>
        public bool AllowNull
        {
            get
            {
                if (_AllowNull == null)
                    _AllowNull = ClrType.IsClass || (ClrType.IsGenericType && ClrType.GetGenericTypeDefinition() == typeof(Nullable<>));
                return _AllowNull ?? false;
            }

            set
            {
                _AllowNull = value;
            }
        }

        /// <summary>
        /// Gets or sets the type of the column, or null if column type should be defined using <see cref="ClrType"/> result.
        /// </summary>
        public DbType? OverrideDatabaseType { get; set; }

        /// <summary>
        /// Gets the CLR type of result stored in column.
        /// </summary>
        public abstract Type ClrType { get; }

        /// <summary>
        /// When overriden in derived classes, returns actual column role in table.
        /// </summary>
        public abstract ColumnType ColumnType { get; }

        /// <summary>
        /// Get or set result defines is column should be skipped on generating INSERT statement.
        /// </summary>
        public virtual bool SkipOnInsert { get; set; }

        /// <summary>
        /// Gets or sets a result indicating whether column should not take part in generating UPDATE statement.
        /// </summary>
        public bool SkipOnUpdate { get; set; }
    }
}
